﻿using LitJson;
using LNet;
using OestsCommon.Model;
using OestsDataBase;
using OestsServer.Managers;
using OestsServer.Net;
using System.Collections.Generic;
using Utils;

namespace OestsServer.Handlers.UnityHandlers
{
    /// <summary>
    ///  协议：R
    /// </summary>
    public class RoomHandler : HandlerBase<UnityClientChannel>
    {
        public override PacketKey PKey
        {
            get
            {
                return PacketKey.Room;
            }
        }

        public override void Execute(UnityClientChannel client, Request packet)
        {
            base.Execute(client, packet);
            ResponsePacket.ResponseSubCode = packet.RequestSubCode;

            switch (packet.RequestSubCode)
            {
                case SubCode.None:
                    break;
                case SubCode.RoomList:
                    Execute_RoomList(client, packet);
                    break;
                case SubCode.CreateRoom:
                    Execute_CreateRoom(client, packet);
                    break;
                case SubCode.DeleteRoom:
                    Execute_DeleteRoom(client, packet);
                    break;
                case SubCode.JoinRoom:
                    Execute_JoinRoom(client, packet);
                    break;
                case SubCode.LeaveRoom:
                    Execute_LeaveRoom(client, packet);
                    break;
                case SubCode.SetRole:
                    Excute_SetRole(client, packet);
                    break;
                case SubCode.RelieveRole:
                    Excute_RelieveRole(client, packet);
                    break;
                case SubCode.DeletePlayer:
                    Execute_DeletePlayer(client, packet);
                    break;
                case SubCode.StartSingleTask:
                    Execute_StartSingleTask(client, packet);
                    break;
                case SubCode.UpdateRoom:
                    Execute_UpdateRoom(client, packet);
                    break;
                case SubCode.RoomSartTask:
                    Execute_RoomSartTask(client, packet);
                    break;



                case SubCode.AbortTask:
                    Execute_AbortTask(client, packet);
                    break;
            }
        }
        //终止任务
        public void Execute_AbortTask(UnityClientChannel client, Request packet)
        {
            // DP<int ,int> data = JsonMapper.ToObject<DP<int, int>>(packet.DataStr);
            Dictionary<string, object> dic = JsonMapper.ToObject<Dictionary<string, object>>(packet.DataStr);
            int taskID = (int)dic.TryGet(ParameterCode.StudentID.ToString());
            int roomId = (int)dic.TryGet(ParameterCode.RoomID.ToString());
            ResponsePacket.DataObject = dic;
            UnityClientChannel.Signal_Project_Room.Dispatch(client.ProjectType, roomId, ResponsePacket);
            //删除被终止任务的房间
            RoomManager.RemoveRoom(roomId);
        }

        public void Execute_UpdateRoom(UnityClientChannel client, Request packet)
        {
            int roomId = int.Parse(packet.DataStr);
            ResponsePacket.DataObject = RoomManager.GetRoomById(roomId);
            client.Send(ResponsePacket);
        }

        public void Execute_DeletePlayer(ClientChannel client, Request packet)
        {
            //int[] arr = JsonMapper.ToObject<int[]>(packet.DataStr);
            //foreach (var room in RoomManager.Instance.RoomList)
            //{
            //    if (room.RoomId == arr[0])
            //    {
            //        //删除成员
            //        room.StudentTemps.Remove(arr[1]);
            //        //清除该玩家扮演的岗位信息
            //        if (room.DicPostIdStudentId.ContainsValue(arr[1]))
            //        {
            //            foreach (var item in room.DicPostIdStudentId)
            //            {
            //                if (item.Value == arr[1])
            //                {
            //                    room.DicPostIdStudentId[item.Key] = 0;
            //                    break;
            //                }
            //            }
            //        }
            //        //反馈任务开始
            //        ResponsePacket.DataObject = arr;

            //        //广播 
            //        BroadcastInRoom(room, ResponsePacket);
            //        SendToStudent(arr[1], ResponsePacket);//删除掉的学员接收
            //        break;
            //    }
            //}
        }


        public void Execute_StartSingleTask(UnityClientChannel client, Request packet)
        {
            if (client.Student != null)
            {
                TaskModel task = JsonMapper.ToObject<TaskModel>(packet.DataStr);
                client.Student.CurrentTask = task;
                List<PostTaskModel> models = PostTaskDAL.GetData();
                foreach (var model in models)
                {
                    if (model.TaskId == task.Id)
                    {
                        PostModel p = PostDAL.GetPostModel(model.PostId);
                        client.Student.CurrentPost = p;
                        break;
                    }
                }
                //反馈任务开始
                ResponsePacket.DataObject = task;
                client.Send(ResponsePacket);
            }
        }

        /// <summary>
        /// 创建房间
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        private void Execute_CreateRoom(UnityClientChannel client, Request packet)
        {
            Room r = JsonMapper.ToObject<Room>(packet.DataStr);
            if (RoomManager.CheckRoomIsExist(r.RoomName))
            {
                ResponsePacket = new Response(packet)
                {
                    DataObject = r,
                    ReturnCode = ReturnCode.Fail,
                    RetrunMessage = "创建房间失败，房间名已经存在！"
                };
                client.Send(ResponsePacket);
                return;
            }
            Room room = RoomManager.AddRoom(client.ProjectType, client.Student.DBid, r.RoomName, r.RoomPassword, r.Task);
            //给学员房间属性赋值
            client.Student._room = room;
            Response res = new Response
            {
                ResponseCode = PacketKey.Room,
                ResponseSubCode = SubCode.CreateRoom,
                ReturnCode = ReturnCode.Success,
                DataObject = room
            };
            client.Send(res);  //只向创建者发送消息

            /****相同客户端广播房间列表信息***/
            BroadcastRoomList(client.ProjectType, room.Task.Id);
        }

        /// <summary>
        /// 暂时未用
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        private void Execute_JoinRoom(UnityClientChannel client, Request packet)
        {
            //接收到数据解析：房间id 密码
            Struct2<int, string> roomIdPwd = JsonMapper.ToObject<Struct2<int, string>>(packet.DataStr);

            int roomId = roomIdPwd.Value1;
            string roomPwd = roomIdPwd.Value2;

            #region 得到房间
            foreach (var room in RoomManager.roomList)
            {
                if (room.RoomId == roomId)
                {
                    //验证密码
                    if (room.RoomPassword != roomPwd)
                    {
                        ResponsePacket.DataObject = room;
                        ResponsePacket.ReturnCode = ReturnCode.Fail;
                        ResponsePacket.RetrunMessage = "密码错误";
                        client.Send(ResponsePacket);
                        return;
                    }
                    //加入房间
                    break;
                }
            }
            #endregion
            #region 房间不存在
            //房间不存在
            ResponsePacket.ReturnCode = ReturnCode.Fail;
            ResponsePacket.RetrunMessage = "加入房间失败，房间不存在！";
            ResponsePacket.DataObject = null;
            client.Send(ResponsePacket);
            return;
            #endregion

        }

        public void LeaveRoom(Room room, int studentId)
        {
            ////移除成员信息
            //if (room.StudentTemps.Contains(studentId))
            //{
            //    room.StudentTemps.Remove(studentId);
            //}
            ////如果离开的成员已选择了岗位，清除选择的岗位
            //if (room.DicPostIdStudentId.ContainsValue(studentId))
            //{
            //    foreach (var item in room.DicPostIdStudentId)
            //    {
            //        if (item.Value == studentId)
            //        {
            //            room.DicPostIdStudentId[item.Key] = 0;
            //            break;
            //        }
            //    }
            //}
            //Struct2<Room, int> data = new Struct2<Room, int>();
            //data.Value1 = room;
            //data.Value2 = studentId;
            //ResponsePacket.DataObject = data;
            ////广播
            //BroadcastInRoom(room, ResponsePacket);
        }

        private void Execute_LeaveRoom(UnityClientChannel client, Request packet)
        {
            int houseOwnerId = int.Parse(packet.DataStr);
            int studentId = client.Student.DBid;

            foreach (var room in RoomManager.roomList)
            {
                if (room.RoomId == houseOwnerId)
                {
                    LeaveRoom(room, studentId);
                    //由于自己被移除了  不在房间里面，所以另外发送
                    client.Send(ResponsePacket);
                    break;
                }
            }
        }

        private void Execute_DeleteRoom(UnityClientChannel client, Request packet)
        {

            int roomId = int.Parse(packet.DataStr);

            RoomManager.DeleteRoom(roomId);

            ResponsePacket.ReturnCode = ReturnCode.Success;
            ResponsePacket.ResponseSubCode = SubCode.DeleteRoom;
            ResponsePacket.DataObject = roomId;
            UnityClientChannel.Signal_Project.Dispatch(client.ProjectType, ResponsePacket);
        }

        private void Execute_StartMultiTask(ClientChannel client, Request packet)
        {
            //int roomId = int.Parse(packet.DataStr);
            //foreach (var r in RoomManager.Instance.RoomList)
            //{
            //    if (r.RoomId == roomId)
            //    {
            //        //遍历房间中的所有玩家，检查所有玩家是否都选择了岗位
            //        for (int i = 0; i < r.StudentTemps.Count; i++)
            //        {
            //            if (!r.DicPostIdStudentId.ContainsValue(r.StudentTemps[i]))
            //            {
            //                ResponsePacket.ReturnCode = ReturnCode.Fail;
            //                ResponsePacket.RetrunMessage = "玩家未指定岗位，无法开始！";
            //                ResponsePacket.DataObject = r;
            //                client.Send(ResponsePacket);
            //                return;
            //            }
            //        }
            //        //均选择了岗位
            //        ResponsePacket.ReturnCode = ReturnCode.Success;
            //        ResponsePacket.DataObject = r;
            //        //如果全部由玩家扮演，提示积分，如果有电脑扮演，提示不积分
            //        if (r.StudentTemps.Count == r.DicPostIdStudentId.Count)
            //        {
            //            ResponsePacket.RetrunMessage = "本次任务中所有岗位均由玩家扮演，将会进行积分！";
            //        }
            //        else
            //        {
            //            ResponsePacket.RetrunMessage = "本次任务中有岗位为电脑扮演，不会积分！";
            //        }
            //        r.InGame = true;
            //        BroadcastInRoom(r, ResponsePacket);
            //        break;
            //    }
            //}
        }


        /// <summary>
        /// LYM 设置岗位 
        /// 1、加入房间并设置岗位
        /// 2、已经在房间的 更换岗位信息
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        private void Excute_SetRole(UnityClientChannel client, Request packet)
        {
            Struct2<int, int> data = JsonMapper.ToObject<Struct2<int, int>>(packet.DataStr);
            int roomId = data.Value1;
            int post = data.Value2;
            foreach (var room in RoomManager.roomList)
            {
                if (room.RoomId == roomId)
                {
                    room.SetRole(client.Student, post);

                    //设置Student 的 房间属性
                    client.Student._room = room;
                    //向所有同类客服端学员用户广播Room
                    ResponsePacket.ReturnCode = ReturnCode.Success;
                    ResponsePacket.DataObject = room;
                    UnityClientChannel.Signal_Project.Dispatch(client.ProjectType, ResponsePacket);
                    return;
                }
            }
            ///房间不存在
            ResponsePacket.ReturnCode = ReturnCode.Fail;
            ResponsePacket.RetrunMessage = "加入房间失败，房间不存在！";
            client.Send(ResponsePacket);
            return;

        }

        private void Excute_RelieveRole(UnityClientChannel client, Request packet)
        {
            int roomId = int.Parse(packet.DataStr);
            //得到成员
            if (client.Student != null)
            {
                if (client.Student._room != null)
                {
                    client.Student._room.DelMember(client.Student.DBid);
                    ResponsePacket.ReturnCode = ReturnCode.Success;
                    ResponsePacket.DataObject = client.Student._room;
                    client.Student._room = null;
                    //由于自己已经被移除房间，所以不能在使用房间广播功能，单独发送
                    client.Send(ResponsePacket);
                    //向所有人广播消息
                    UnityClientChannel.Signal_Project.Dispatch(client.ProjectType, ResponsePacket);
                }
                else
                {
                    ResponsePacket.ReturnCode = ReturnCode.Fail;
                    ResponsePacket.RetrunMessage = "你不在房间内！";
                    client.Send(ResponsePacket);
                }
            }
            else
            {
                ResponsePacket.ReturnCode = ReturnCode.Fail;
                ResponsePacket.RetrunMessage = "用户不存在或者用户类型不是学员！";
                client.Send(ResponsePacket);
            }
        }

        /// <summary>
        /// 房间开始任务
        /// 接收：房间ID int
        /// 房间成员广播 Room
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        private void Execute_RoomSartTask(UnityClientChannel client, Request packet)
        {
            int roomId = int.Parse(packet.DataStr);
            Room r = RoomManager.GetRoomById(roomId);
            r.InGame = true;
            ResponsePacket.ReturnCode = ReturnCode.Success;
            ResponsePacket.DataObject = r;
            //向所有人发送广播消息
            UnityClientChannel.Signal_Project.Dispatch(client.ProjectType, ResponsePacket);
        }



        private void Execute_SetPost(UnityClientChannel client, Request packet)
        {
            //Struct3<int, int, int> data = JsonMapper.ToObject<Struct3<int, int, int>>(packet.DataStr);

            //if (data != null)
            //{
            //    //协议解析
            //    int roomId = data.Value1;
            //    int studentId = data.Value2;
            //    int postId = data.Value3;

            //    foreach (var r in RoomManager.Instance.RoomList)
            //    {
            //        if (r.RoomId == roomId)
            //        {
            //            if (r.DicPostIdStudentId.ContainsKey(postId.ToString()))
            //            {
            //                //表示该岗位已经有人扮演了，新的学员将要代替就的学员扮演该岗位,旧的学员设置的岗位请客，广播出去
            //                if (r.DicPostIdStudentId[postId.ToString()] > 0 && r.DicPostIdStudentId[postId.ToString()] != studentId)
            //                {
            //                    Response cancelPostPacket = new Response();
            //                    cancelPostPacket.ResponseCode = PacketKey.Game;
            //                    cancelPostPacket.ResponseSubCode = SubCode.SetRole;
            //                    cancelPostPacket.ReturnCode = ReturnCode.Success;
            //                    cancelPostPacket.DataObject = new Struct3<int, int, int>() { Value1 = roomId, Value2 = r.DicPostIdStudentId[postId.ToString()], Value3 = 0 };
            //                    BroadcastInRoom(r, cancelPostPacket);
            //                }

            //                //如果该用户已经扮演了岗位，清除扮演信息
            //                //if (r.DicPostIdStudentId.ContainsValue(studentId))
            //                //{
            //                //    foreach (var item in r.DicPostIdStudentId)
            //                //    {
            //                //        if (item.Value == studentId)
            //                //        {
            //                //            Packet cancelPostPacket = new Packet();
            //                //            cancelPostPacket.Key = PacketKey.Game;
            //                //            cancelPostPacket.ResponseSubCode = SubCode.SetPost;
            //                //            cancelPostPacket.ReturnCode = ReturnCode.Success;
            //                //            cancelPostPacket.DataObject = new Struct3<int, int, int>() { Value1 = roomId, Value2 = studentId, Value3 = 0 };
            //                //            r.DicPostIdStudentId[item.Key] = 0;
            //                //            BroadcastInRoom(r, cancelPostPacket);
            //                //            break;
            //                //        }
            //                //    }
            //                //}
            //                //设置岗位新的扮演者
            //                r.DicPostIdStudentId[postId.ToString()] = studentId;
            //            }
            //            ResponsePacket.DataObject = data;
            //            //房间广播
            //            BroadcastInRoom(r, ResponsePacket);
            //            break;
            //        }
            //    }
            //}
        }

        /// <summary>
        /// 更新房间列表，根据任务ID获取当前任务的房间
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        public void Execute_RoomList(UnityClientChannel client, Request packet)
        {
            int taskId = int.Parse(packet.DataStr);
            Struct2<int, List<Room>> data = GetRoomList(client.ProjectType, taskId);
            ResponsePacket.ReturnCode = ReturnCode.Success;
            ResponsePacket.DataObject = data;
            client.Send(ResponsePacket);
        }

        public static void BroadcastRoomList(ProjectType client, int taskId)
        {
            Struct2<int, List<Room>> data = GetRoomList(client, taskId);
            Response bcRes = new Response
            {
                ResponseCode = PacketKey.Room,
                ReturnCode = ReturnCode.Success,
                ResponseSubCode = SubCode.RoomList,
                DataObject = data
            };
            UnityClientChannel.Signal_Project.Dispatch(client, bcRes);
        }

        private static Struct2<int, List<Room>> GetRoomList(ProjectType client, int taskId)
        {
            List<Room> listRoom = RoomManager.GetRoomList(client, taskId);
            Struct2<int, List<Room>> data = new Struct2<int, List<Room>>
            {
                Value1 = taskId,
                Value2 = listRoom
            };
            return data;
        }

    }
}
